package com.dhcc.sds.busi.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.dhcc.cdc.busi.dao.CdcLocationMapper;
import com.dhcc.cdc.busi.entity.CdcDictionaryEntity;
import com.dhcc.cdc.busi.entity.CdcEpisodeEntity;
import com.dhcc.cdc.busi.entity.CdcLocationEntity;
import com.dhcc.cdc.busi.service.ICdcDictionaryService;
import com.dhcc.cdc.busi.service.ICdcEpisodeService;
import com.dhcc.cdc.busi.service.ICdcLocationService;
import com.dhcc.cdc.sys.entity.DictionaryEntity;
import com.dhcc.cdc.sys.service.IDictionaryService;
import com.dhcc.core.framework.base.service.impl.BaseServiceImpl;
import com.dhcc.sdc.busi.entity.SdcBusiQcTriggeredEntity;
import com.dhcc.sdc.busi.entity.SdcQcEntity;
import com.dhcc.sds.base.cache.formitem.FormItemCache;
import com.dhcc.sds.base.entity.SdsQcentityEntity;
import com.dhcc.sds.base.entity.SdsQcformItemEntity;
import com.dhcc.sds.base.service.ISdsCommonService;
import com.dhcc.sds.base.service.ISdsQcentityService;
import com.dhcc.sds.busi.dao.SdsQcincaseDataMapper;

import com.dhcc.sds.busi.entity.*;
import com.dhcc.sds.busi.service.*;
import com.dhcc.sds.busi.vo.AnalysisSdsPortalVo;
import com.dhcc.sds.util.DateUtil;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 表单常用门户相关信息获取服务层接口实现
 *
 * @author zhangdc
 * @ClassName: SdsQcincaseDataServiceImpl
 * @Description: TODO
 * @date 2022-06-01 10:09:15
 */
@Service("sdsQcincaseDataService")
public class SdsQcincaseDataServiceImpl extends BaseServiceImpl<SdsQcincaseDataMapper, SdsQcincaseDataEntity> implements ISdsQcincaseDataService {


    @Autowired
    private ISdsQcincaseService sdsQcincaseService;
    @Autowired
    private ICdcEpisodeService cdcEpisodeService;
    @Autowired
    private ISdsQcincaseOperlogService sdsQcincaseOperlogService;
    @Autowired
    private ICdcDictionaryService cdcDictionaryService;
    @Autowired
    private ISdsQcfitemExecresultService sdsQcfitemExecresultService;
    @Autowired
    private ISdsCommonService sdsCommonService;
    @Autowired
    private ISdsQcentityService sdsQcentityService;
    @Autowired
    private IDictionaryService dictionaryService;
    @Autowired
    private ISdsDimAliasService sdsDimAliasService;
    @Autowired
    private ISdsDimDataService sdsDimDataService;
    @Autowired
    private ICdcLocationService cdcLocationService;

    private Lock lock = new ReentrantLock();   // 创建锁对象

    @Override
    public void updatePortalData(Long mrId) {
        //更新门户所需单病种病例数据
        SdsQcincaseEntity sdsQcincaseEntity = sdsQcincaseService.selectById(mrId);
        updateMrData(mrId, sdsQcincaseEntity);
        if (StringUtils.isEmpty(sdsQcincaseEntity)) {
            return;
        }
        CdcEpisodeEntity cdcEpisodeEntity = cdcEpisodeService.selectById(sdsQcincaseEntity.getEpisodeId());
        Date dishDate = cdcEpisodeEntity.getDishDate();
        // 获取就诊院区ID
        CdcLocationEntity locationEntity = cdcLocationService.selectOne(new EntityWrapper<CdcLocationEntity>().eq("xcode", cdcEpisodeEntity.getAdmLocId()));
        Long hospId = locationEntity.getHospitalId();
        int year = 0;
        int month = 0;
        if (!StringUtils.isEmpty(dishDate)) {
            String y = com.dhcc.core.framework.util.DateUtil.formatDate(dishDate, "yyyy");
            String m = com.dhcc.core.framework.util.DateUtil.formatDate(dishDate, "MM");
            year = Integer.parseInt(y);
            month = Integer.parseInt(m);
        }
        //默认其他疾病系统
        //String entityCat = sdsCommonService.getDictDesc("EntityCat", "7");
        SdsQcentityEntity sdsQcentityEntity = sdsQcentityService.selectById(sdsQcincaseEntity.getEntityId());
        DictionaryEntity dictionaryEntity = dictionaryService.selectById(sdsQcentityEntity.getEntityCatId());
        String entityCat = dictionaryEntity.getDescription();
        //首先删除对照关系
        List<SdsDimAliasEntity> sdsDimAliasEntities = sdsDimAliasService.selectList(new EntityWrapper<SdsDimAliasEntity>()
                .eq("mr_id", mrId));
        for (SdsDimAliasEntity sdsDimAliasEntity : sdsDimAliasEntities) {
            //对应维护数量-1
            this.dimDataCountChange(sdsDimAliasEntity.getDimDataId(), -1);
            sdsDimAliasService.deleteById(sdsDimAliasEntity.getId());
        }

        //更新数据主记录以及对照关系
        this.updateDimData(hospId, "DisDate", year, month, entityCat, sdsQcincaseEntity.getState(), mrId);

        //上传状态的表单，需要同时更新上传日期维度数据
        if (Objects.equals("Up", sdsQcincaseEntity.getState())) {
            SdsQcincaseOperlogEntity sdsQcincaseOperlogEntity = sdsQcincaseOperlogService.selectLastOne(mrId, "Up");
            String y = com.dhcc.core.framework.util.DateUtil.formatDate(sdsQcincaseOperlogEntity.getOperDate(), "yyyy");
            String m = com.dhcc.core.framework.util.DateUtil.formatDate(sdsQcincaseOperlogEntity.getOperDate(), "MM");
            year = Integer.parseInt(y);
            month = Integer.parseInt(m);
            this.updateDimData(hospId, "UpLoadDate", year, month, entityCat, sdsQcincaseEntity.getState(), mrId);
        }

    }

    @Override
    public int selectRepCount(Map<String, Object> params) {
        return this.baseMapper.selectRepCount(params);
    }

    @Override
    public AnalysisSdsPortalVo selectCostAndDayByDimData(Long dimDataId) {
        return this.baseMapper.selectCostAndDayByDimData(dimDataId);
    }

    @Override
    public List<AnalysisSdsPortalVo> selectQCUpLoadData(Map<String, Object> params) {
        return this.baseMapper.selectQCUpLoadData(params);
    }

    @Override
    public List<AnalysisSdsPortalVo> selectLocUpLoadData(Map<String, Object> params) {
        return this.baseMapper.selectLocUpLoadData(params);
    }

    @Override
    public List<AnalysisSdsPortalVo> selectDocUpLoadData(Map<String, Object> params) {
        return this.baseMapper.selectDocUpLoadData(params);
    }

    @Override
    public List<AnalysisSdsPortalVo> selectARatio(Map<String, Object> params) {
        return this.baseMapper.selectARatio(params);
    }

    @Override
    public List<AnalysisSdsPortalVo> selectUseTime(Map<String, Object> params) {
        return this.baseMapper.selectUseTime(params);
    }

    @Override
    public List<AnalysisSdsPortalVo> selectMrlistDataDetails(String idName, List<String> deptIds) {
        return this.baseMapper.selectMrlistDataDetails(idName, deptIds);
    }

    @Override
    public List<SdsQcincaseDataEntity> selectByUploadDateAndUserLinkDepts(String uploadDate, Map<String, Object> params) {
        return this.baseMapper.selectByUploadDateAndUserLinkDepts(uploadDate, params);
    }

    @Override
    public List<CdcEpisodeEntity> selectQCDept(Map<String, Object> params) {
        return this.baseMapper.selectQCDept(params);
    }

    @Override
    public List<SdcBusiQcTriggeredEntity> selectQCCategory(Map<String, Object> params) {
        return this.baseMapper.selectQCCategory(params);
    }

    @Override
    public List<SdcBusiQcTriggeredEntity> selectQCCategoryByCondition(Map<String, Object> params) {
        return this.baseMapper.selectQCCategoryByCondition(params);
    }

    /**
     * @Description: 查询质控触发人次
     * @return: 触发人次数
     * @author: yanghangwei
     * @date:2023年8月10日 上午11:10:22
     */
    @Override
    public int selectTriggerCountByDate(String startDate, String endDate, Map<String, Object> params) {
        return this.baseMapper.selectTriggerCountByDate(startDate, endDate, params);
    }

    @Override
    public List<CdcEpisodeEntity> selectPatientDetail(Long id) {
        return this.baseMapper.selectPatientDetail(id);
    }


    @Override
    public List<SdcQcEntity> selectQcDetail(Long id) {
        return this.baseMapper.selectQcDetail(id);
    }

    @Override
    public List<SdsQcincaseDataEntity> selectDaysByEntityId(Long entityId) {
        return this.baseMapper.selectDaysByEntityId(entityId);
    }

    @Override
    public AnalysisSdsPortalVo selectARatioByTime(Long entityId, Map<String, Object> params) {
        return this.baseMapper.selectARatioByTime(entityId, params);
    }

    @Override
    public List<AnalysisSdsPortalVo> selectUseTimeByTime(Long entityId, Map<String, Object> params) {
        return this.baseMapper.selectUseTimeByTime(entityId, params);
    }

    @Override
    public List<AnalysisSdsPortalVo> selectdevlist(Map<String, Object> params) {
        return this.baseMapper.selectdevlist(params);
    }

    private void updateMrData(Long mrId, SdsQcincaseEntity sdsQcincaseEntity){
//        SdsQcincaseEntity sdsQcincaseEntity = sdsQcincaseService.selectById(mrId);
        if (!StringUtils.isEmpty(sdsQcincaseEntity)){
            SdsQcincaseDataEntity sdsQcincaseDataEntity = new SdsQcincaseDataEntity();
            //就诊类型:门诊
            CdcDictionaryEntity admTypeO = cdcDictionaryService.queryByTypeCodeAndCode("PatData", "bus_adm_type", "O");
            //就诊类型:住院
            CdcDictionaryEntity admTypeI = cdcDictionaryService.queryByTypeCodeAndCode("PatData", "bus_adm_type", "I");
            CdcEpisodeEntity cdcEpisodeEntity = cdcEpisodeService.selectById(sdsQcincaseEntity.getEpisodeId());
            //区分门诊和住院
            //迟报天数
            int lastUpDays = -1;
            //住院日
            int hospDays = 0;
            //住院费用
            BigDecimal hospCost = new BigDecimal("0.00");
            //上报日期
            Date uploadDate = null;
            //操作日期
            Date operDate = null;
            SdsQcincaseOperlogEntity sdsQcincaseOperlogEntity = sdsQcincaseOperlogService.selectLastOne(mrId, sdsQcincaseEntity.getState());
            operDate = sdsQcincaseOperlogEntity.getOperDate();
            if (Objects.equals(admTypeO.getId(), cdcEpisodeEntity.getBusAdmTypeId())){
                //门诊
                if (Objects.equals("Up", sdsQcincaseEntity.getState())){
                    //SdsQcincaseOperlogEntity sdsQcincaseOperlogEntity = sdsQcincaseOperlogService.selectLastOne(mrId, sdsQcincaseEntity.getState());
                    lastUpDays = Math.toIntExact(DateUtil.getDateCompare(sdsQcincaseOperlogEntity.getOperDate(), cdcEpisodeEntity.getAdmDate(), "d"));
                    uploadDate = sdsQcincaseOperlogEntity.getOperDate();
                }else {
                    lastUpDays = Math.toIntExact(DateUtil.getDateCompare(new Date(), cdcEpisodeEntity.getAdmDate(), "d"));
                }
            }else if (Objects.equals(admTypeI.getId(), cdcEpisodeEntity.getBusAdmTypeId())){
                //住院
                if (Objects.equals("Up", sdsQcincaseEntity.getState())){
                    //SdsQcincaseOperlogEntity sdsQcincaseOperlogEntity = sdsQcincaseOperlogService.selectLastOne(mrId, sdsQcincaseEntity.getState());
                    lastUpDays = Math.toIntExact(DateUtil.getDateCompare(sdsQcincaseOperlogEntity.getOperDate(), new Date(sdsQcincaseEntity.getInDate().getTime() + sdsQcincaseEntity.getInTime().getTime()), "d"));
                    uploadDate = sdsQcincaseOperlogEntity.getOperDate();
                }else {
                    lastUpDays = Math.toIntExact(DateUtil.getDateCompare(new Date(), new Date(sdsQcincaseEntity.getInDate().getTime() + sdsQcincaseEntity.getInTime().getTime()), "d"));
                }
                hospDays = cdcEpisodeEntity.getAdmDays();
                SdsQcformItemEntity formItem = FormItemCache.me().getFormItemByCode(sdsQcincaseEntity.getEntityId(), "CM-6-1");
                if (!StringUtils.isEmpty(formItem)){
                    String valueByFormIdAndCaseId = sdsQcfitemExecresultService.getValueByFormIdAndCaseId(formItem.getId(), sdsQcincaseEntity.getId());
                    if (!StringUtils.isEmpty(valueByFormIdAndCaseId)){
                        hospCost = hospCost.add(new BigDecimal(valueByFormIdAndCaseId));
                    }
                }

            }
            //自动采集率
            String autoAlias = sdsQcincaseService.getAutoAlias(mrId);
            //填报累积用时
            Long fillUseTime = sdsQcincaseService.getMrUseTime(mrId);

            sdsQcincaseDataEntity.setMrId(mrId);
            sdsQcincaseDataEntity = this.baseMapper.selectOne(sdsQcincaseDataEntity);
            if (null == sdsQcincaseDataEntity){
                sdsQcincaseDataEntity = new SdsQcincaseDataEntity();
                sdsQcincaseDataEntity.setMrId(mrId);
                sdsQcincaseDataEntity.setMrStatus(sdsQcincaseEntity.getState());
                sdsQcincaseDataEntity.setLocId(cdcEpisodeEntity.getAdmLocId());
                sdsQcincaseDataEntity.setLocDesc(cdcEpisodeEntity.getAdmLocDesc());
                sdsQcincaseDataEntity.setDocId(cdcEpisodeEntity.getAdmDoctorId());
                sdsQcincaseDataEntity.setDocName(cdcEpisodeEntity.getAdmDoctorName());
                sdsQcincaseDataEntity.setEntityId(sdsQcincaseEntity.getEntityId());
                sdsQcincaseDataEntity.setHospCost(hospCost);
                sdsQcincaseDataEntity.setHospDays(hospDays);
                sdsQcincaseDataEntity.setAutoFillRatio(autoAlias);
                sdsQcincaseDataEntity.setFillUseTime(fillUseTime);
                sdsQcincaseDataEntity.setUploadDate(uploadDate);
                sdsQcincaseDataEntity.setLastUpDays(lastUpDays);
                sdsQcincaseDataEntity.setAdmType(cdcEpisodeEntity.getBusAdmTypeId());
                sdsQcincaseDataEntity.setOperDate(operDate);
                sdsQcincaseDataEntity.insert();
            }else {
                sdsQcincaseDataEntity.setMrStatus(sdsQcincaseEntity.getState());
                sdsQcincaseDataEntity.setLocId(cdcEpisodeEntity.getAdmLocId());
                sdsQcincaseDataEntity.setLocDesc(cdcEpisodeEntity.getAdmLocDesc());
                sdsQcincaseDataEntity.setDocId(cdcEpisodeEntity.getAdmDoctorId());
                sdsQcincaseDataEntity.setDocName(cdcEpisodeEntity.getAdmDoctorName());
                sdsQcincaseDataEntity.setEntityId(sdsQcincaseEntity.getEntityId());
                sdsQcincaseDataEntity.setHospCost(hospCost);
                sdsQcincaseDataEntity.setHospDays(hospDays);
                sdsQcincaseDataEntity.setAutoFillRatio(autoAlias);
                sdsQcincaseDataEntity.setFillUseTime(fillUseTime);
                sdsQcincaseDataEntity.setUploadDate(uploadDate);
                sdsQcincaseDataEntity.setLastUpDays(lastUpDays);
                sdsQcincaseDataEntity.setAdmType(cdcEpisodeEntity.getBusAdmTypeId());
                sdsQcincaseDataEntity.setOperDate(operDate);
                sdsQcincaseDataEntity.updateAllColumnById();
            }






        }
    }

    private void dimDataCountChange(Long dimDataId, Integer count){
        synchronized (SdsQcincaseDataServiceImpl.class){
            SdsDimDataEntity sdsDimDataEntity = sdsDimDataService.selectById(dimDataId);
            if (!StringUtils.isEmpty(sdsDimDataEntity)){
                sdsDimDataEntity.setMrCount(sdsDimDataEntity.getMrCount() + count);
                sdsDimDataEntity.updateAllColumnById();
            }
        }
    }

    private void updateDimData(Long hospId, String dimType, Integer year, Integer month,
                               String disease, String mrStatus, Long aMrlistId){
        SdsDimDataEntity sdsDimDataEntity = sdsDimDataService.selectOne(new EntityWrapper<SdsDimDataEntity>()
                .eq("dim_hosp", hospId)
                .eq("dim_type", dimType)
                .eq("dim_year", year)
                .eq("dim_month", month)
                .eq("disease", disease)
                .eq("mr_status", mrStatus));
        if (!StringUtils.isEmpty(sdsDimDataEntity)){
            //对应维护数量+1
            this.dimDataCountChange(sdsDimDataEntity.getId(), 1);
            SdsDimAliasEntity sdsDimAliasEntity = new SdsDimAliasEntity();
            sdsDimAliasEntity.setDimDataId(sdsDimDataEntity.getId());
            sdsDimAliasEntity.setMrId(aMrlistId);
            sdsDimAliasService.insertOrUpdate(sdsDimAliasEntity);
        }else {
            sdsDimDataEntity = new SdsDimDataEntity();
            sdsDimDataEntity.setDimHosp(hospId);
            sdsDimDataEntity.setDimType(dimType);
            sdsDimDataEntity.setDimYear(year);
            sdsDimDataEntity.setDimMonth(month);
            sdsDimDataEntity.setDisease(disease);
            sdsDimDataEntity.setMrStatus(mrStatus);
            sdsDimDataEntity.setMrCount(1);
            sdsDimDataEntity.insert();
            SdsDimAliasEntity sdsDimAliasEntity = new SdsDimAliasEntity();
            sdsDimAliasEntity.setDimDataId(sdsDimDataEntity.getId());
            sdsDimAliasEntity.setMrId(aMrlistId);
            sdsDimAliasService.insertOrUpdate(sdsDimAliasEntity);
        }

    }
}
